//
//  BackgroundRes.m
//  CandyJump
//
//  Created by Bon Lam on 02/04/2011.
//  Copyright 2011 Peru Republic. All rights reserved.
//

#import "BackgroundRes.h"

#import "BackgroundObject.h"
#import "BackgroundObject+ProtectedMethods.h"

#import "AnimationRes.h"

#import "PRFile.h"

#define BACKGROUND_RES_FILENAME						@"StaticData/Scenes/%@.xml"

#define BACKGROUND_RES_ELEM_TAG_BGINFO				@"backgroundInfo"

#define BACKGROUND_RES_XML_ELEM_TAG_OBJECT				@"object"
#define BACKGROUND_RES_XML_ELEM_TAG_SPRITE				@"sprite"
#define BACKGROUND_RES_XML_ELEM_TAG_ANIMATION			@"animationInfo"
#define BACKGROUND_RES_XML_ELEM_TAG_BASIC_SETTINGS		@"basicSettings"
#define BACKGROUND_RES_XML_ELEM_TAG_SETTINGS			@"settings"

#define BACKGROUND_RES_XML_ATTR_TAG_FILE				@"file"

//=====================================================================================================================
@implementation BackgroundInfo

@synthesize gravity;
@synthesize pattern;


@end

//=====================================================================================================================
@implementation BackgroundRes

@synthesize backgroundInfo;
@synthesize backgroundModelArray;

static BackgroundRes *sharedRes = nil;

#pragma mark -
#pragma mark Singleton Object Functions
//---------------------------------------------------------------------------------------------------------------------
- (id)init
{
	self = [super init];
	if (self == nil)  {return self;}
	
	return self;
}

//---------------------------------------------------------------------------------------------------------------------
- (void)dealloc
{
	[backgroundInfo release];
	backgroundInfo = nil;
	
	[backgroundModelArray release];
	backgroundModelArray = nil;
	
	[super dealloc];
}

//---------------------------------------------------------------------------------------------------------------------
+ (id)allocWithZone:(NSZone *)zone
{
    return [[self sharedRes] retain];
}

//---------------------------------------------------------------------------------------------------------------------
- (id)copyWithZone:(NSZone *)zone
{
    return self;
}

//---------------------------------------------------------------------------------------------------------------------
- (id)retain 
{
    return self;
}

//---------------------------------------------------------------------------------------------------------------------
- (NSUInteger)retainCount
{
    return NSUIntegerMax;  //denotes an object that cannot be released
}

//---------------------------------------------------------------------------------------------------------------------
- (void)release
{
    //do nothing
}

//---------------------------------------------------------------------------------------------------------------------
- (id)autorelease
{
    return self;
}

#pragma mark Custom Functions
//---------------------------------------------------------------------------------------------------------------------
+ (BackgroundRes *)sharedRes
{
    if (sharedRes == nil) {
        sharedRes = [[super allocWithZone:NULL] init];
    }
    return sharedRes;
}

//---------------------------------------------------------------------------------------------------------------------
- (void)loadBackground:(NSString*)backgroundName
{
	if (backgroundInfo != nil) {
		[backgroundInfo release];
		backgroundInfo = nil;
	}
	
	backgroundInfo = [[BackgroundInfo alloc] init];
	
	if (backgroundModelArray != nil) {
		[backgroundModelArray release];
		backgroundModelArray = nil;
	}
	
	backgroundModelArray = [[NSMutableArray alloc] init];
	
	NSString* filename = [NSString stringWithFormat:BACKGROUND_RES_FILENAME, backgroundName];
	NSString* filePath = [PRFile getFilePath:filename];
	
	BOOL loadedBackground = [self parseXMLFile:filePath];
	
	NSAssert(loadedBackground == YES, @"[BackgroundRes loadBackground:backgroundName] Error - parseXMLFile returned false");
	
	return;
}

//---------------------------------------------------------------------------------------------------------------------
- (void)unloadBackground
{
	for (BackgroundObject *object in backgroundModelArray) {
		[object removeSpriteFromParent];
	}
	
	[backgroundModelArray release];
	backgroundModelArray = nil;
}

#pragma mark NSXMLParserDelegate
//---------------------------------------------------------------------------------------------------------------------
- (BOOL)parseXMLFile:(NSString *)filename
{
	//  Load Background XML file
	NSData *xmlData = [NSData dataWithContentsOfFile:filename];
	
	NSAssert(xmlData != nil, @"[BackgroundRes parseXMLFile:filename] Error - Unable to load file data: ""%@""", filename);
	
	NSError* error = nil;
	[self parseXMLData:xmlData parseError:&error];
	
	return (error == nil);
}

//---------------------------------------------------------------------------------------------------------------------
- (void)parseXMLData:(NSData *)data parseError:(NSError **)error
{
	NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
    [parser setDelegate:self];
    [parser setShouldProcessNamespaces:NO];
    [parser setShouldReportNamespacePrefixes:NO];
    [parser setShouldResolveExternalEntities:NO];
    [parser parse];
	
    NSError *parseError = [parser parserError];
    if (parseError && error)  {
        *error = parseError;
    }
    [parser release];
}

//---------------------------------------------------------------------------------------------------------------------
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
	if ([elementName isEqualToString:BACKGROUND_RES_ELEM_TAG_BGINFO])
	{
		NSAssert(backgroundInfo != nil, @"[ObjectRes parser: didStartElement: namespaceURI: qualifiedName: attributes:] Error - backgroundInfo is nil");
		
		for (NSString* key in [attributeDict allKeys]) {
			id value = [attributeDict objectForKey:key];
			[backgroundInfo setValue:value forKey:key];
		}
		
		return;
	}
	
	if ([elementName isEqualToString:BACKGROUND_RES_XML_ELEM_TAG_OBJECT])
	{
		BackgroundObject *object = [[BackgroundObject alloc] init];
		
		[backgroundModelArray addObject:object];
		currentReadingObject = [object retain];
		[object release];
	}
	
	if ([elementName isEqualToString:BACKGROUND_RES_XML_ELEM_TAG_SPRITE]) {
		
		if (currentReadingObject == nil) {return;}
		
		for (NSString* key in [attributeDict allKeys]) {
			id value = [attributeDict objectForKey:key];
			[currentReadingObject setValue:value forKey:key];
		}
		return;
	}
	
	if ([elementName isEqualToString:BACKGROUND_RES_XML_ELEM_TAG_ANIMATION]) {
		
		if (currentReadingObject == nil) {return;}
		NSString* animationName = [attributeDict valueForKey:BACKGROUND_RES_XML_ATTR_TAG_FILE];
		currentReadingObject.animationDictionary = [[AnimationRes sharedRes] loadAnimation:animationName];
		
		return;
	}
	
	if ([elementName isEqualToString:BACKGROUND_RES_XML_ELEM_TAG_SETTINGS] ||
		[elementName isEqualToString:BACKGROUND_RES_XML_ELEM_TAG_BASIC_SETTINGS]) {
		
		if (currentReadingObject == nil) {return;}
		
		for (NSString* key in [attributeDict allKeys]) {
			id value = [attributeDict objectForKey:key];
			[currentReadingObject setValue:value forKey:key];
		}
		return;
	}
}

//---------------------------------------------------------------------------------------------------------------------
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
	if ([elementName isEqualToString:BACKGROUND_RES_XML_ELEM_TAG_OBJECT]) {
		[currentReadingObject release];
		currentReadingObject = nil;
	}
}

//---------------------------------------------------------------------------------------------------------------------
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
{
	
}

//---------------------------------------------------------------------------------------------------------------------
- (void)parserDidEndDocument:(NSXMLParser *)parser
{	
}
@end
